
Date.prototype.Format = function (fmt) {
  // author: meizz
  var o = {
    'M+': this.getMonth() + 1, // 月份
    'd+': this.getDate(), // 日
    'h+': this.getHours(), // 小时
    'm+': this.getMinutes(), // 分
    's+': this.getSeconds(), // 秒
    'q+': Math.floor((this.getMonth() + 3) / 3), // 季度
    S: this.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(
      RegExp.$1,
      (this.getFullYear() + '').substr(4 - RegExp.$1.length)
    )
  }
  for (var k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      )
    }
  }
  return fmt
}

/**
 *
 * 时间计算，加减乘除
 *
 * @param date {Mix} {String,Object(time)}
 * @param delta  int
 * @param type  年y 月m 日d
 *
 * //todo
 */

export const dateCalc = (date, delta, type) => {
  let d

  if ((typeof date).toLocaleLowerCase() === 'Object') {
    d = new Date(date.getTime())
  } else {
    d = new Date(String(date).replace('/-/g', '/'))
  }

  switch (type) {
  case 'y':
    d.setFullYear(d.getFullYear() + delta)
    break
  case 'm':
    d.setMonth(d.getMonth() + delta)
    break
  case 'd':
    d.setDate(d.getDate() + delta)
    break
  default:
    d.setDate(d.getDate() + delta)
  }
  return d
}

/**
 *
 * 日期计算
 *
 * @param date {Mix} {String,Object(time)}
 * @param delta  int
 * @param type  年y 月m 日d
 *
 * //todo
 */

export const dateCalcByDate = (begin, end) => {
  let d, t

  if ((typeof begin).toLocaleLowerCase() === 'Object') {
    d = new Date(begin.getTime())
  } else {
    d = new Date(String(begin).replace('/-/g', '/'))
  }

  if ((typeof end).toLocaleLowerCase() === 'Object') {
    t = new Date(end.getTime())
  } else {
    t = new Date(String(end).replace('/-/g', '/'))
  }

  const delta = t.getTime() - d.getTime() // 毫秒

  const milliseconds = delta
  const seconds = Math.floor(delta / 1000)
  const minites = Math.floor(delta / (1000 * 60))
  const hours = Math.floor(delta / (1000 * 3600))
  const days = Math.floor(delta / (1000 * 3600 * 24))
  const months = (t.getFullYear() * 12 + t.getMonth()) - (d.getFullYear() * 12 + d.getMonth())
  const years = t.getFullYear() - d.getFullYear()

  return {
    milliseconds,
    seconds,
    minites,
    hours,
    days,
    months,
    years
  }
}

// 本地储存
export const gridStorage = {
  set (key, val) {
    if (!sessionStorage) {
      return
    }
    if (!key || !val) {
      return
    }
    sessionStorage.setItem(key, JSON.stringify(val))
  },
  get (key) {
    let rs = null
    if (!sessionStorage) {
      return rs
    }
    if (!sessionStorage || !key) { return rs }
    rs = sessionStorage.getItem(key)
    try {
      rs = JSON.parse(rs)
    } catch (e) {
      rs = null
    }
    return rs
  },
  remove (key) {
    if (!sessionStorage) {
      return rs
    }
    sessionStorage.removeItem(key)
  },
  clear () {
    if (!sessionStorage) {
      return rs
    }
    sessionStorage.clear()
  }
}

// localStorage本地储存
export const localStore = {
  set (key, val) {
    if (!localStorage) {
      return
    }
    if (!key || !val) {
      return
    }
    localStorage.setItem(key, val)
  },
  get (key) {
    if (!localStorage || !key) { return }
    return localStorage.getItem(key)
  },
  remove (key) {
    if (!localStorage) {
      return
    }
    localStorage.removeItem(key)
  },
  clear () {
    if (!localStorage) {
      return
    }
    localStorage.clear()
  }
}

// 菜单项管理
export const tabManager = {
  getRouterByName (arr, name) {
    return arr.filter(o => {
      return name === o.name || name === (o.meta ? o.meta.title : 'NO_FIT')
    })[0] || null
  },
  removeActivedClass (arr) {
    arr.forEach(o => {
      o.active = false
    })
    return arr
  },
  setActive (arr, name) {
    arr.forEach(o => {
      o.active = name === o.name
    })
    return arr
  },
  saveData (routers) {
    gridStorage.set('gridPageList', routers)
  },
  clear () {
    gridStorage.set('gridPageList', [])
  },
  getRouter () {
    return gridStorage.get('gridPageList') || []
  },
  add (routers, o) {
    if (!o || !routers) {
      return
    }

    this.removeActivedClass(routers)

    routers.push({
      tabText: o.meta.title,
      tabName: o.name,
      name: o.name,
      active: true,
      bufferPath: o.fullPath  //缓存query路径
    })

    return routers
  },

  removeRouterByName (arr, name) {
    return arr.filter(o => {
      return name !== o.name
    })
  }

}

//在浏览器里打开新的页面
//href不包含origin和pathname
export const newPage = function(href){
  let origin = ""
  let pathname = ""
  if(window && window.location){
    origin = window.location.origin
    pathname = window.location.pathname === "/" ? "" : window.location.pathname
  }
  href = origin + pathname + href;
  const dom = document.createElement('a')
  dom.href = href
  dom.target = '_blank';
  dom.style = {
    visibility: 'hidden',
    display: 'block'
  }

  document.body.appendChild(dom) // 新开页
  dom.click()
}


function isPlainObject (obj) {
  const toString = [].toString
  const hasOwn = Object.prototype.hasOwnProperty
  const types = {
    '[object Boolean]': 'bool',
    '[object Number]': 'number',
    '[object String]': 'string',
    '[object Object]': 'object',
    '[object Array]': 'array',
    '[object Function]': 'function',
    '[object Date]': 'date',
    '[object RegExp]': 'regExp'
  }
  const type = function (obj) {
    return obj === null ? String(obj) : types[toString.call(obj)] || 'object'
  }
  const isWindow = function (obj) {
    return obj && typeof obj === 'object' && 'setInterval' in obj
  }
  const isArray = Array.isArray || function (obj) {
    return type(obj) === 'array'
  }

  if (!obj || type(obj) !== 'object' || isWindow(obj) || obj.nodeType) {
    return false
  }
  try {
    if (obj.constructor && !hasOwn.call(obj, 'constructor') &&
      !hasOwn.call(obj.constructor.prototype, 'isPrototypeOf')) {
      return false
    }
  } catch (e) {
    return false
  }
  var key
  for (key in obj) {}
  return key === undefined || hasOwn.call(obj, key)
}

function cusExtend () {
  let options; let name; let src; let copy; let copyIsArray; let clone
  let target = arguments[0] || {}
  let i = 1
  let length = arguments.length
  let deep = false

  // Handle a deep copy situation
  // 判断是否是深拷贝，如$.extend(true,object1,boject2)
  // deep变为true,target变为object1
  if (typeof target === 'boolean') {
    deep = target
    target = arguments[1] || {}
    // skip the boolean and the target
    i = 2
  }

  // Handle case when target is a string or something (possible in deep copy)
  // 用来处理不正确的参数，target必须是object或者函数类型，如果不是，赋值一个空的{}
  if (typeof target !== 'object' && !Object.prototype.toString.call(target) === '[object Function]') {
    target = {}
  }

  // extend jQuery itself if only one argument is passed
  // 当只有一个参数时，用来扩展方法，如插件的使用
  if (length === i) {
    target = this// 当jQuery.extend()时，this指jQuery，添加工具方法；jQuery.fn.extend(),this指jQuery.fn，添加实例方法
    --i
  }

  for (; i < length; i++) {
    // Only deal with non-null/undefined values
    if ((options = arguments[ i ]) != null) {
      // Extend the base object
      for (let key in options) {
        src = target[ key ]
        copy = options[ key ]

        // Prevent never-ending loop
        // 因为var a = {};
        // a.name=a;这种情况会无限循环，a.name.name.name.name...要避免这种情况
        if (target === copy) {
          continue
        }

        // Recurse if we're merging plain objects or arrays
        // 当deep为真，copy存在并且copy时对象自变量（{}，new Object）或array，执行
        if (deep && copy && (isPlainObject(copy) || (copyIsArray = Array.isArray(copy)))) {
          if (copyIsArray) {
            copyIsArray = false
            clone = src && Array.isArray(src) ? src : []// src存在并且是数组，src不变，否则赋值空数组
          } else {
            // src存在并且是对象自变量，src值不变，否则赋值{}
            clone = src && isPlainObject(src) ? src : {}
          }

          // Never move original objects, clone them
          /* 举例说明：
                     *
                     *var a = { name : { job : 'it' } };
                      var b = { name : {age : 30} };
                      由于copy=b[name]是{age:30},对象自变量，就要再次调用extend(true,a[name],b[name])
                      b[name].age是number不是对象自变量，直接执行target[ name ] = copy;
                      a[name]就是{job : 'it'，age : 30}
                      */

          target[ key ] = cusExtend(deep, clone, copy)

          // Don't bring in undefined values
        } else if (copy !== undefined) {
          target[ key ] = copy
        }
      }
    }
  }

  // Return the modified object
  return target
}

export const deepClone = cusExtend

export const $storage = gridStorage
export const $simpleStore = gridStorage
